#include "base.h"
#include "intr.h"
#include "protect.h"
#include "page.h"
#include "kparam.h"

PUBLIC char kstack[4 * 1024];

#define PD_PHY		0x00100000
#define PT_PHY		0x00101000

#ifdef PG_SIZE
#undef PG_SIZE
#define PG_SIZE		0x1000
#else
#define PG_SIZE		0x1000
#endif

int pre_setup_pd(void){
	uint_32 *pd_p = (uint_32 *)PD_PHY;
	uint_32 pt_entry;
	uint_32 pd_index;

	pt_entry = 0x00101000 + PT_P + PT_RW + PT_U;

	/* make linear address space from 0x00000000 to 0x00100000 and 
	 * from 0xC0000000 to 0xFFFFFFFF map the same physical address from
	 * 0 to 1M
	 */
	//*(pd_p + 0) = pt_entry;

	PD_INDEX(pd_index, K_VM);
	*(pd_p + pd_index) = pt_entry;
	
	/*
	 * setup the kernel map page
	 */
	PD_INDEX(pd_index, KMAP_VM);
	*(pd_p + pd_index) = pt_entry;
	return 0;
}

int pre_setup_pt(void){
	uint_32 *pt_p = (uint_32 *)PT_PHY;

	int i = 0;

	/* first 1M address need 256 pages */
	for (i = 0; i < 256; i++){
		*(pt_p + i) = (PG_SIZE * i + PG_P + PG_RW + PG_U);
	}

	/* map the kmap */
	PT_INDEX(i, KMAP_VM);
	*(pt_p + i) = (uint_32)kmap + PG_P + PG_RW + PG_U;
	return 0;
}

int setup_tss(struct seg_desc *tss_desc,struct tss_t *tss, uint_32 esp0){
	tss_desc->seg_base_l = (uint_16)((uint_32)tss & 0x0000FFFF);
	tss_desc->seg_base_m = (uint_8) (((uint_32)tss >> 0x10) & 0x000000FF);
	tss_desc->seg_base_h = (uint_8) (((uint_32)tss >> 0x18) & 0x000000FF);
	
	tss->esp0 = K_STACK;
	tss->ss0 = 0x10;
	
	tss->esp = esp0;
	tss->ss = 0x28;
	return 0;
}


int map_intr_handler(struct gate_desc idt[]){
	int i = 0;
	int vector ;
	intr_hook_t hook = NULL;
	
	for (; intr_handler_array[i].intr_vector != INVALID; i++){
		hook = intr_handler_array[i].intr_hook;
		vector = intr_handler_array[i].intr_vector;
		idt[vector].gate_offset_l = (uint_16)((uint_32)hook & 0x0000FFFF);
		idt[vector].gate_selector = KERNEL_CODE_SEL;
		idt[vector].gate_attr.resv= 0;
		idt[vector].gate_attr.type= INTR_GATE_386;
		idt[vector].gate_attr.s = 0;
		idt[vector].gate_attr.dpl = intr_handler_array[i].priv;
		idt[vector].gate_attr.p = 1;
		idt[vector].gate_offset_h = (uint_16)(((uint_32)hook >> 0x10) & 0x0000FFFF);
	}

	return 0;
}


